Skip to content

feat: migration ui#1501

Merged
Haz3-jolt merged 4 commits into
Observal:mainfrom
naraen-ram:feat/migration-admin-dash
Jun 28, 2026
Merged

feat: migration ui#1501
Haz3-jolt merged 4 commits into
Observal:mainfrom
naraen-ram:feat/migration-admin-dash

Conversation

@naraen-ram

@naraen-ram naraen-ram commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Purpose / Description

Brings the existing observal migrate CLI capabilities into the settings, so a super_admin can move an Observal instance's data in a few clicks without using the CLI.

Today, migrating data requires an operator to know and correctly sequence CLI commands, manage connection strings, and shuttle archive files between machines by hand. This feature reduces that to three operations driven from the UI:

  1. Export — the server dumps its own connected PostgreSQL data, ClickHouse telemetry data, or both into downloadable .tar.gz archives.
  2. Import — the operator uploads previously-exported archives and the server loads them into its own databases with automatic org ID rewriting.
  3. Validate — standalone checksum, row-count, and FK reference verification on archives without importing.

All operations run as background jobs on the existing arq worker, with progress streamed to the UI and artifacts offered for download when ready. The existing CLI commands remain fully functional — both the UI and CLI share the same migration service core.

Approach

Architecture

  • Shared Migration Service (observal-server/services/migration/): Extracted all migration logic from cmd_migrate.py into a shared, import-light package with no typer/rich/FastAPI dependencies at module scope. Both the CLI and the server import from this core.

  • REST API (api/routes/admin/migrate.py): 8 endpoints for export/import/validate (start + status polling + artifact download + current-org). All require super_admin role. Concurrency check prevents duplicate jobs. Upload validation checks magic bytes and size.

  • Background Job (jobs/migration.py): run_migration_job loads the job row, creates artifact directory (0o700), dispatches to the shared service, writes progress to DB (throttled 1s), and handles success/failure with audit events. purge_migration_artifacts cron deletes expired artifacts.

  • Frontend (web/src/pages/admin/settings.tsx, web/src/pages/admin/dashboard/components/migrate-*.tsx): Data Migration section in Settings (super_admin-gated, between Registered Agents Only and Data Retention), tabbed dialog (Export/Import/Validate), spinner-based progress, result display with download buttons.

  • PostgreSQL Model + Alembic Migration: MigrationJob table with enums for operation/scope/status, progress fields, result JSON, and artifact metadata.

Key Design Decisions

  • CLI imports server's shared core (Option A from design doc): True single source of truth. CLI keeps operating on operator-supplied URLs while server uses its own connections.
  • Polling over WebSockets: TanStack Query refetchInterval (1.5s) while job is active. Simpler, survives reconnects, matches existing InsightReport pattern.
  • Auto org rewrite on import: Target instance's org is auto-detected and all org references are rewritten, so imported data is immediately visible.
  • Telemetry packed into single tar.gz: Export produces exactly two files (pg_export.tar.gz + telemetry_export.tar.gz) for clean UX.

How Has This Been Tested?

  1. Unit tests (tests/test_migration_*.py, observal_cli/tests/test_cmd_migrate.py):

    • Service import isolation (no framework deps)
    • CLI commands invoke shared service correctly (11 tests)
    • REST API endpoints (202, 409, 422, 403, audit events)
    • Background job lifecycle (status transitions, throttling, errors)
    • Artifact security (token minting, expiry, path traversal protection)
  2. Property-based tests (Hypothesis, tests/test_migration_properties.py):

    • 15 properties covering: round-trip preservation, FK-safe ordering, schema tolerance, idempotent CH import, org rewrite, row accounting, checksum failure, validation, state machine, credential exclusion, token expiry, TTL purge, role denial
  3. Integration tests (tests/test_migration_integration.py):

    • Export→validate round-trip
    • Idempotent re-import (ON CONFLICT DO NOTHING)
    • TTL purge removes aged directories
  4. Manual E2E testing against local Docker stack:

    • Export (PostgreSQL only, PostgreSQL+ClickHouse both) ✓
    • Import with org rewrite ✓
    • Validate ✓
    • Download artifacts ✓
    • Concurrency check (409) ✓
image image image image

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)

Licenses

Library Description License
pyarrow Apache Parquet read/write for ClickHouse telemetry export/import Apache 2.0

AI Assistance

  • Yes: Kiro (Claude)
  • Was the generated code manually reviewed and tested?

@github-actions github-actions Bot added cli CLI changes server Pull request touches server code tests Pull request adds or modifies tests web Pull request touches web frontend code Has Conflicts Pull request has merge conflicts and removed Has Conflicts Pull request has merge conflicts labels Jun 23, 2026
@naraen-ram naraen-ram force-pushed the feat/migration-admin-dash branch from 3722f5d to 4099f98 Compare June 23, 2026 07:42
@github-actions github-actions Bot added the Has Conflicts Pull request has merge conflicts label Jun 23, 2026
@naraen-ram naraen-ram changed the title Feat/migration admin dash feat/migration admin dash Jun 23, 2026
@github-actions github-actions Bot removed the Has Conflicts Pull request has merge conflicts label Jun 23, 2026
@naraen-ram naraen-ram force-pushed the feat/migration-admin-dash branch from d0a6045 to e1eaa8c Compare June 23, 2026 07:47
@github-actions github-actions Bot added Has Conflicts Pull request has merge conflicts and removed Has Conflicts Pull request has merge conflicts labels Jun 23, 2026
@naraen-ram naraen-ram force-pushed the feat/migration-admin-dash branch from d017d24 to fb19e0c Compare June 23, 2026 07:54
@github-actions github-actions Bot added Has Conflicts Pull request has merge conflicts and removed Has Conflicts Pull request has merge conflicts labels Jun 23, 2026
@naraen-ram naraen-ram force-pushed the feat/migration-admin-dash branch from 2bfae39 to 67b4bcd Compare June 23, 2026 08:10
@Haz3-jolt

Copy link
Copy Markdown
Contributor

This should be in settings, not in exec dashboard

@naraen-ram naraen-ram changed the title feat/migration admin dash feat: migration ui Jun 25, 2026
@naraen-ram naraen-ram force-pushed the feat/migration-admin-dash branch from 34aa839 to aec0044 Compare June 28, 2026 06:10
@Haz3-jolt Haz3-jolt force-pushed the feat/migration-admin-dash branch 6 times, most recently from 3a7c24b to 2b1dabd Compare June 28, 2026 14:09
naraen-ram and others added 3 commits June 28, 2026 14:33
Co-authored-by: Hari Srinivasan <harisrini21@gmail.com>
Co-authored-by: Hari Srinivasan <harisrini21@gmail.com>
Co-authored-by: Hari Srinivasan <harisrini21@gmail.com>
Co-authored-by: Hari Srinivasan <harisrini21@gmail.com>
@Haz3-jolt Haz3-jolt force-pushed the feat/migration-admin-dash branch from 2b1dabd to e3f3dae Compare June 28, 2026 14:33
@Haz3-jolt Haz3-jolt merged commit 5db4526 into Observal:main Jun 28, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI changes server Pull request touches server code tests Pull request adds or modifies tests web Pull request touches web frontend code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants